namespace ndk
{
inline
int epoll_reactor_handler_repository::unbind(ndk_handle handle)
{
  STRACE("epoll_reactor_handler_repository");
  if (this->find(handle) == 0)
    return -1;
  this->handlers_[handle].event_handler_ = 0;
  this->handlers_[handle].mask_ = event_handler::null_mask;
  return 0;
}
inline
event_handler *epoll_reactor_handler_repository::find(ndk_handle handle,
                                                   size_t *index_p/* = 0*/)
{
  STRACE("epoll_reactor_handler_repository");
  event_handler *eh = 0;
  if (this->handle_in_range(handle))
  {
    eh = this->handlers_[handle].event_handler_;
    if (eh && index_p) *index_p = handle;
  }
  return eh;
}
inline
int epoll_reactor_handler_repository::bind(ndk_handle handle,
                                           event_handler *eh,
                                           reactor_mask mask)
{
  STRACE("epoll_reactor_handler_repository");
  if (eh == 0 || this->handlers_ == 0)
    return -1;
  if (this->is_invalid_handle(handle)) return -1;
  this->handlers_[handle].event_handler_ = eh;
  this->handlers_[handle].mask_ = mask;
  return 0;
}
inline
reactor_mask epoll_reactor_handler_repository::mask(ndk_handle handle)
{
  if (this->handle_in_range (handle))
    return this->handlers_[handle].mask_;
  return event_handler::null_mask;
}
inline
void epoll_reactor_handler_repository::mask(ndk_handle handle,
                                            reactor_mask mask)
{
  if (this->handle_in_range(handle))
    this->handlers_[handle].mask_ = mask;
}
inline
int epoll_reactor_handler_repository::handle_in_range(ndk_handle handle) const
{
  if (handle >= 0 && handle < this->max_size_)
    return 1;
  return 0;
}
inline
int epoll_reactor_handler_repository::is_invalid_handle(ndk_handle handle) const
{
  if (handle < 0 || handle >= this->max_size_)
    return 1;
  return 0;
}
// --------------------------------------------------------------------------
inline
int epoll_reactor_notify::read_notify_pipe(ndk_handle ,
                                          notification_buffer &buffer)
{
  return ndk::read(this->notification_pipe_.read_handle(),
                   (char *)&buffer,
                   sizeof(buffer));
}
inline
int epoll_reactor_notify::handle_input(ndk_handle handle)
{
  STRACE("epoll_reactor_notify");
  notification_buffer buffer;
  this->read_notify_pipe(handle, buffer);
  return 0;
}
inline
ndk_handle epoll_reactor_notify::notify_handle()
{
  return this->notification_pipe_.read_handle();
}
// ------------------------------------------------------------------------
inline 
static void polite_sleep_hook(void *) { }
inline
int epoll_reactor::token_guard::acquire_quietly(const time_value *timeout/* = 0*/)
{
  STRACE("epoll_reactor::token_guard");
  int result = 0;
  if (timeout == 0)
  {
    result = this->token_.acquire_read(&polite_sleep_hook);
  }else
  {
    result = this->token_.acquire_read(&polite_sleep_hook,
                                        0,
                                        timeout);
  }
  if (result == 0) this->owner_ = 1;
  return result;
}
inline
int epoll_reactor::token_guard::acquire(const time_value *timeout/* = 0*/)
{
  STRACE("epoll_reactor::token_guard");
  int result = 0;
  if (timeout == 0)
  {
    result = this->token_.acquire();
  }else
  {
    result = this->token_.acquire(0, 0, timeout);
  }
  if (result == 0) this->owner_ = 1;
  return result;
}
inline
void epoll_reactor::token_guard::release_token(void)
{
  if (this->owner_ == 1)
  {
    this->token_.release();
    this->owner_ = 0;
  }
}
// -------------------------------------------------------------------------
inline
int epoll_reactor::deactivated(void) 
{
  return this->deactivated_;
}
inline
void epoll_reactor::deactivate(int do_stop) 
{
  this->deactivated_ = do_stop;

}
inline
int epoll_reactor::register_handler(event_handler *eh, 
                                    reactor_mask mask) 
{
  STRACE("epoll_reactor");
  guard<epoll_reactor_token> g(this->token_);
  return this->register_handler_i(eh->get_handle(),
                                   eh,
                                   mask);
}
inline
int epoll_reactor::register_handler(ndk_handle io_handle, 
                                    event_handler *eh, 
                                    reactor_mask mask) 
{
  STRACE("epoll_reactor");
  guard<epoll_reactor_token> g(this->token_);
  return this->register_handler_i(io_handle,
                                   eh,
                                   mask);
}
inline
int epoll_reactor::remove_handler(event_handler *eh, 
                                  reactor_mask mask) 
{
  STRACE("epoll_reactor");
  guard<epoll_reactor_token> g(this->token_);
  return this->remove_handler_i(eh->get_handle(),
                                mask);
}
inline
int epoll_reactor::remove_handler(ndk_handle io_handle, 
                                  reactor_mask mask) 
{
  STRACE("epoll_reactor");
  guard<epoll_reactor_token> g(this->token_);
  return this->remove_handler_i(io_handle,
                                mask);
}
inline
int epoll_reactor::schedule_timer(event_handler *eh,
                                  const void *arg,
                                  const time_value &delay,
                                  const time_value &interval/* = time_value::zero*/)
{
  STRACE("epoll_reactor");
  if (0 == this->timer_queue_) return -1;

  guard<epoll_reactor_token> g(this->token_);
  int result = this->timer_queue_->schedule(eh,
                                            arg,
                                            delay,
                                            interval);
  if (result != -1)
  {
    if (interval != time_value::zero)
    {
      this->incre_payload();
    }
  }
  return result;
}
inline
int epoll_reactor::crontab(const event_handler *eh,
                           const void *arg,
                           const char *entry)
{
  STRACE("epoll_reactor");
  if (0 == this->timer_queue_) return -1;

  guard<epoll_reactor_token> g(this->token_);
  int result = this->timer_queue_->crontab(eh,
                                           arg,
                                           entry);
  if (result != -1)
    this->incre_payload();
  return result;
}
inline
int epoll_reactor::reset_timer_interval(int timer_id,
                                        const time_value &interval)
{
  STRACE("epoll_reactor"); 
  if (0 == this->timer_queue_) return -1;

  guard<epoll_reactor_token> g(this->token_);
  return this->timer_queue_->reset_interval(timer_id, interval);
}
inline
int epoll_reactor::cancel_timer(int timer_id,
                                const void **arg/* = 0*/,
                                int dont_call_handle_close/* = 1*/)
{
  STRACE("epoll_reactor"); 
  if (0 == this->timer_queue_) return -1;

  guard<epoll_reactor_token> g(this->token_);
  if (this->timer_queue_->cancel(timer_id,
                                 arg,
                                 dont_call_handle_close) == 0)
  {
    this->decre_payload();
    return 0;
  }
  return -1;
}
inline
int epoll_reactor::cancel_timer(event_handler *event_handler,
                                int dont_call_handle_close/* = 1*/)
{
  STRACE("epoll_reactor");
  if (0 == this->timer_queue_) return 0;

  guard<epoll_reactor_token> g(this->token_);
  if (this->timer_queue_->cancel(event_handler,
                                 dont_call_handle_close) == 0)
  {
    this->decre_payload();
    return 0;
  }
  return -1;
}
inline
int epoll_reactor::notify(event_handler *eh,
                          reactor_mask mask)
{
  STRACE("epoll_reactor");
  return this->notify_handler_->notify(eh, mask);
}
inline
int epoll_reactor::purge_pending_notifications(event_handler *eh,
                                               reactor_mask mask)
{
  STRACE("epoll_reactor");
  if (eh == 0) return -1;
  return this->notify_handler_->purge_pending_notifications(eh, mask);
}
inline
int epoll_reactor::upcall(event_handler *eh,
                          int (event_handler::*callback)(ndk_handle),
                          ndk_handle handle)
{
  return (eh->*callback)(handle);
}
inline
token &epoll_reactor::lock()
{
    return this->token_;
}
inline
size_t epoll_reactor::size(void) const
{
  return this->size_;
}
inline
size_t epoll_reactor::curr_payload()
{
  guard<thread_mutex> g(this->curr_payload_mutex_);
  return this->curr_payload_;
}
inline
thread_t epoll_reactor::owner()
{
  //guard<epoll_reactor_token> g(this->token_);
  return this->owner_;
}
inline
void epoll_reactor::owner(thread_t /*thr_id*/)
{
  //guard<epoll_reactor_token> g(this->token_);
  //this->owner_ = thr_id;
  return ;
}
inline
void epoll_reactor::incre_payload(int n/* = 1*/)
{
  this->curr_payload_mutex_.acquire();
  this->curr_payload_ += n;
  this->curr_payload_mutex_.release();
}
inline
void epoll_reactor::decre_payload(int n/* = 1*/)
{
  this->curr_payload_mutex_.acquire();
  this->curr_payload_ += n;
  this->curr_payload_mutex_.release();
}
} // namespace ndk

